package main

import (
	"context"
	"fmt"
	"net/http"

	"golang.org/x/sync/errgroup"
)

func main() {
	lock := &sync.Mutex{}
	counter := HystrixWindowCounter{
		WindowSecond :1
		WindowNum    :60
		RequestMaxCount : 600
	}

	g, ctx := errgroup.WithContext(context.Background())

	mux := http.NewServeMux()
	mux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
		counter.Execute(
			func() {
				w.Write([]byte("pong"))
			}, 
			func() {
				fmt.Printf("we have an error: "+err.)
			}
		)
	})

	server := http.Server{
		Handler: mux,
		Addr:    ":8080",
	}

	g.Go(func() error {
		return server.ListenAndServe()
	})

	fmt.Printf("errgroup exiting: %+v\n", g.Wait())
}

// 计数器
type HystrixWindowCounter struct {
	WindowSecond int64
	WindowNum    int64
	RequestMaxCount int64
	WindowList   map[int64]int64
}

func (this *HystrixWindowCounter) Execute(f1 func(), f2 func()) {
	lock.Lock()

	nowsecond := int64(time.Now().Unix())
	start_second := nowsecond - this.WindowNum
	del_request_count := int64(0)
	ExistFlag := false

	for k, v := range this.WindowList {
		if k < start_second {
			delete(this.WindowList, k)
			del_request_count += v
		}

		if k == nowsecond {
			this.WindowList[k] += 1
			ExistFlag = true
		}
	}

	if !ExistFlag {
		this.WindowList[nowsecond] = 1
	}

	this.RequestCount = this.RequestCount - del_request_count + 1

	lock.Unlock()

	if this.RequestCount >= this.RequestMaxCount {
		f2()
	}

	f1()
}
